#include "PreviewImageUI.h"
#include "MatUtil.h"
PreviewImageUI::PreviewImageUI()
    : m_hBitmap(NULL)
{
    ::SetRect(&m_selectedRect, 0, 0, 0, 0);
    m_startPoint.x = 0;
    m_startPoint.y = 0;
    m_endPoint.x = 0;
    m_endPoint.y = 0;
}

PreviewImageUI::~PreviewImageUI()
{
    if (m_hBitmap)
    {
        DeleteObject(m_hBitmap);
        m_hBitmap = NULL;
    }
}

void PreviewImageUI::SetBitmap(HBITMAP hBitmap)
{
    if (m_hBitmap)
    {
        DeleteObject(m_hBitmap);
        m_hBitmap = NULL;
    }
    m_fscale = 1.0f;
    m_hBitmap = hBitmap;
    if (m_hBitmap)
    {
        BITMAP bm;
        GetObject(m_hBitmap, sizeof(bm), &bm);

        m_bmpWidth = bm.bmWidth;
        m_bmpHeight = bm.bmHeight;

        RECT rc = GetPos();

        // 计算居中位置
        int destX = (rc.right - rc.left - m_bmpWidth) / 2;
        int destY = (rc.bottom - rc.top - m_bmpHeight) / 2;

        m_bmpDrawPoint.x = rc.left + destX;
        m_bmpDrawPoint.y = rc.top + destY;
    }

    Invalidate();
}

void PreviewImageUI::ClearBitmap()
{
    if (m_hBitmap)
    {
        DeleteObject(m_hBitmap);
        m_hBitmap = NULL;
    }
    Invalidate();
}

void PreviewImageUI::StartSelect()
{
    m_selectState = SELECTING;
    ::SetRect(&m_selectedRect, 0, 0, 0, 0);
}

void PreviewImageUI::DoEvent(TEventUI &event)
{
    CControlUI::DoEvent(event);
    if (event.Type == UIEVENT_MOUSEENTER)
    {
        if (m_selectState == SELECTING)
            SetCursor(DUI_CROSS);
        else if (m_selectState == SELECT_GET_COLOR)
            SetCursor(DUI_CROSS);
    }
    else if (event.Type == UIEVENT_MOUSELEAVE)
    {
        SetCursor(DUI_ARROW);
        return;
    }
    else if (event.Type == UIEVENT_BUTTONDOWN)
    {
        POINT pt = {event.ptMouse.x, event.ptMouse.y};
        if (m_selectState == SELECT_NONE || m_selectState == SELECT_COMPLETE)
        {
            m_startPoint = pt;
            m_selectState = Select_DRAG;
            return;
        }

        RECT rc = GetPos();

        // 转换为相对坐标
        pt.x -= rc.left;
        pt.y -= rc.top;

        if (m_selectState == SELECTING)
        {
            // 第一次点击，设置起始点
            m_startPoint = pt;
            m_endPoint = pt;
            Invalidate();

            m_selectState = SELECT_FIRST_CLICK;
        }
        else if (m_selectState == SELECT_FIRST_CLICK)
        {
            // 第二次点击，设置结束点并绘制矩形
            m_endPoint = pt;
            Invalidate();

            NotifySelectComplete();
            m_selectState = SELECT_COMPLETE;
        }
    }
    else if (event.Type == UIEVENT_BUTTONUP)
    {
        POINT pt = {event.ptMouse.x, event.ptMouse.y};
        if (m_selectState == Select_DRAG)
        {
            m_selectState = SELECT_NONE;
            return;
        }
        else if (m_selectState == SELECT_GET_COLOR)
        {
            m_selectState = SELECT_NONE;
            POINT cursorPos;
            if (GetCursorPos(&cursorPos))
            {
                HDC hdcScreen = GetDC(NULL);
                if (hdcScreen)
                {
                    COLORREF pixelColor = GetPixel(hdcScreen, cursorPos.x, cursorPos.y);
                    if (m_onGetColor)
                    {
                        BYTE red = GetRValue(pixelColor);
                        BYTE green = GetGValue(pixelColor);
                        BYTE blue = GetBValue(pixelColor);
                        pixelColor = RGB(blue, green, red);
                        pixelColor |= 0xFF000000;
                        m_onGetColor(pixelColor);
                    }
                    ReleaseDC(NULL, hdcScreen);
                }
            }
        }
    }
    else if (event.Type == UIEVENT_MOUSEMOVE)
    {
        POINT pt = {event.ptMouse.x, event.ptMouse.y};

        if (m_selectState == Select_DRAG)
        {
            int dpi = m_pManager->GetDPIObj()->GetDPI();
            m_bmpDrawPoint.x += pt.x - m_startPoint.x;
            m_bmpDrawPoint.y += pt.y - m_startPoint.y;
            m_startPoint = pt;

            Invalidate();
            return;
        }
        if (m_selectState == SELECT_FIRST_CLICK)
        {
            RECT rc = GetPos();

            // 转换为相对坐标
            pt.x -= rc.left;
            pt.y -= rc.top;

            m_endPoint = pt;
            // 计算矩形区域
            m_selectedRect.left = min(m_startPoint.x, m_endPoint.x);
            m_selectedRect.top = min(m_startPoint.y, m_endPoint.y);
            m_selectedRect.right = max(m_startPoint.x, m_endPoint.x);
            m_selectedRect.bottom = max(m_startPoint.y, m_endPoint.y);

            if (m_onSelecting)
            {
                RECT realRect = CalcSelectRect();
                m_onSelecting(realRect);
            }
            Invalidate();
        }
    }
    else if (event.Type == UIEVENT_SCROLLWHEEL)
    {

        LONG dx = event.ptMouse.x - m_bmpDrawPoint.x;
        LONG dy = event.ptMouse.y - m_bmpDrawPoint.y;
        float scaledWidth = (m_bmpWidth * m_fscale);
        float scaledHeight = (m_bmpHeight * m_fscale);

        switch (LOWORD(event.wParam))
        {
        case SB_LINEUP:
            m_fscale += 0.1f;
            break;
        case SB_LINEDOWN:
            m_fscale -= 0.1f;
            break;
        }
        if (m_fscale < 0.1f)
            m_fscale = 0.1f;

        m_bmpDrawPoint.x = event.ptMouse.x - dx / scaledWidth * (m_bmpWidth * m_fscale);
        m_bmpDrawPoint.y = event.ptMouse.y - dy / scaledHeight * (m_bmpHeight * m_fscale);

        Invalidate();
    }
}

void PreviewImageUI::NotifySelectComplete()
{
    if (!m_onSelectComplete)
        return;
    if (!m_hBitmap || m_selectedRect.right <= m_selectedRect.left || m_selectedRect.bottom <= m_selectedRect.top)
        return;

    RECT realRect = CalcSelectRect();
    if (realRect.right <= realRect.left || realRect.bottom <= realRect.top)
        return;

    m_onSelectComplete(realRect);
}

RECT PreviewImageUI::CalcSelectRect()
{
    RECT rc = GetPos();
    RECT realRect = {
        max(m_selectedRect.left + rc.left, m_bmpDrawPoint.x),
        max(m_selectedRect.top + rc.top, m_bmpDrawPoint.y),
        min(m_selectedRect.right + rc.left, (LONG)(m_bmpDrawPoint.x + m_bmpWidth * m_fscale)),
        min(m_selectedRect.bottom + rc.top, (LONG)(m_bmpDrawPoint.y + m_bmpHeight * m_fscale))};
    if (realRect.right <= realRect.left || realRect.bottom <= realRect.top)
        return {};
    realRect.left -= m_bmpDrawPoint.x;
    realRect.top -= m_bmpDrawPoint.y;
    realRect.right -= m_bmpDrawPoint.x;
    realRect.bottom -= m_bmpDrawPoint.y;

    realRect.left /= m_fscale;
    realRect.top /= m_fscale;
    realRect.right /= m_fscale;
    realRect.bottom /= m_fscale;
    return realRect;
}

bool PreviewImageUI::DoPaint(HDC hDC, const RECT &rcPaint, CControlUI *pStopControl)
{
    CControlUI::DoPaint(hDC, rcPaint, pStopControl);
    RECT rc = GetPos();

    // 绘制位图
    if (m_hBitmap)
    {
        // 计算缩放后尺寸
        int scaledWidth = std::floor(m_bmpWidth * m_fscale);
        int scaledHeight = std::floor(m_bmpHeight * m_fscale);

        int destX = m_bmpDrawPoint.x;
        int destY = m_bmpDrawPoint.y;
        int srcX = 0;
        int srcY = 0;
        if (rc.left > m_bmpDrawPoint.x)
        {
            srcX = (rc.left - m_bmpDrawPoint.x) / m_fscale;
            destX = rc.left;
        }
        if (rc.top > m_bmpDrawPoint.y)
        {
            srcY = (rc.top - m_bmpDrawPoint.y) / m_fscale;
            destY = rc.top;
        }
        RECT rcDest = {
            destX,
            destY,
            m_bmpDrawPoint.x + scaledWidth,
            m_bmpDrawPoint.y + scaledHeight};

        RECT rcBmpPart{srcX, srcY, m_bmpWidth, m_bmpHeight};
        RECT rcCorners{0, 0, 0, 0};
        CRenderEngine::DrawImage(hDC, m_hBitmap, rcDest, m_rcPaint, rcBmpPart, rcCorners, false);
    }

    // 绘制最终选择的矩形
    if (m_selectState == SELECT_FIRST_CLICK)
    {
        if (m_selectedRect.right > m_selectedRect.left &&
            m_selectedRect.bottom > m_selectedRect.top)
        {
            HPEN hPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
            HPEN hOldPen = (HPEN)SelectObject(hDC, hPen);
            HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC, GetStockObject(NULL_BRUSH));

            Rectangle(hDC,
                      rc.left + m_selectedRect.left,
                      rc.top + m_selectedRect.top,
                      rc.left + m_selectedRect.right,
                      rc.top + m_selectedRect.bottom);

            SelectObject(hDC, hOldPen);
            SelectObject(hDC, hOldBrush);
            DeleteObject(hPen);
        }
    }

    return true;
}

UINT PreviewImageUI::GetControlFlags() const
{
    if (SELECTING == m_selectState || SELECT_FIRST_CLICK == m_selectState || Select_DRAG == m_selectState || SELECT_GET_COLOR == m_selectState)
        return UIFLAG_SETCURSOR;
    return 0;
}

RECT PreviewImageUI::GetClientRect() const
{
    return GetPos();
}